/**
 * Copyright (C) 2012 Oleg Anastassov <o.anastasov@gmail.com>
 *
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements. See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package kz.kstu.ent.desktop.components.model;

import kz.kstu.ent.desktop.ui.util.SortHelper;

import javax.swing.table.AbstractTableModel;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author Oleg Anastassov
 */
public class SimpleTableModal extends AbstractTableModel implements Sortable {

    private static final Integer UP = 1;
    private static final Integer DOWN = 2;

    private Map<Integer, Integer> columnSortStateMap = new HashMap<Integer, Integer>();

    /**
     * Shown data array.
     */
    private List<Object[]> data = new ArrayList<Object[]>();

    /**
     * Array of column names string.
     */
    private String[] columnNames = new String[]{};

    /**
     * Constructor.
     */
    public SimpleTableModal() {
        super();
    }

    /**
     * Constructor.
     *
     * @param columnNames The array of column names.
     */
    public SimpleTableModal(String... columnNames) {
        super();
        this.columnNames = columnNames;
    }

    /**
     * {@inheritDoc}
     */
    public int getRowCount() {
        return data != null ? data.size() : 0;
    }

    /**
     * {@inheritDoc}
     */
    public int getColumnCount() {
        return columnNames != null ? columnNames.length : 0;
    }

    /**
     * {@inheritDoc}
     */
    public Object getValueAt(int rowIndex, int columnIndex) {
        return data != null ? data.get(rowIndex)[columnIndex] : null;
    }

    /**
     * {@inheritDoc}
     */
    public String getColumnName(int columnIndex) {
        return columnNames != null ? columnNames[columnIndex] : null;
    }

    public List<Object[]> getData() {
        return data;
    }

    public String[] getColumnNames() {
        return columnNames;
    }

    /**
     * Sets specified string array as column headers.
     *
     * @param columnNames The array of column names.
     */
    public void setColumnNames(String... columnNames) {
        this.columnNames = columnNames;
    }

    /**
     * Sets specified string array as column headers.
     *
     * @param dataList The object array list.
     */
    public void setData(List<Object[]> dataList) {
        if (dataList != null) {
            data = dataList;
            fireTableDataChanged();
        } else {
            clear();
        }
    }

    /**
     * Deletes the row from the model.
     *
     * @param rowIndex row index
     */
    public void deleteRow(int rowIndex) {
        data.remove(rowIndex);
        fireTableRowsDeleted(rowIndex, rowIndex);
    }

    /**
     * Use to clear model and selection.
     */
    public void clear() {
        data.clear();
        fireTableDataChanged();
    }

    /**
     * Adds new row to the table model.
     *
     * @param values The values for this row.
     */
    public void addRow(Object... values) {
        data.add(values);
        fireTableRowsInserted(getRowCount(), getRowCount());
    }

    /**
     * Gets row data.
     *
     * @param rowIndex row index
     * @return values
     */
    public Object[] getRow(int rowIndex) {
        return data.get(rowIndex);
    }

    @Override
    public void sortByColumn(int columnIndex) {
        Integer sortMode = columnSortStateMap.get(columnIndex);
        boolean isAscending = sortMode == null || (sortMode.equals(DOWN));
        columnSortStateMap.put(columnIndex, isAscending ? UP : DOWN);
        if (getRowCount() > 0) {
            SortHelper.sortByColumn(data, columnIndex, isAscending, getColumnClass(columnIndex));
            fireTableDataChanged();
        }
    }
}
